﻿#pragma once
#include "resource.h"
#include "Page1.h"

class CCustomTabCtrl : // public CTabCtrlT<ATL::CWindow>
	public CWindowImpl<CCustomTabCtrl, CTabCtrl>// , public COwnerDraw<CCustomTabCtrl>
	
{
public:
	typedef struct _tagTabViewPage
	{
		CDialogImplBase* pWnd;
		LPVOID pData;
	}* PTABVIEWPAGE, TABVIEWPAGE;

	int m_nSel;
	ATL::CAtlList<TABVIEWPAGE> m_tab;

	BEGIN_MSG_MAP(CCustomTabCtrl)
		// MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		Show();
		return 0;
	}

	LRESULT OnTabChange(WPARAM /*wParam*/, LPNMHDR lpNmhdr, BOOL& bHandled)
	{	
		int nSel = GetCurSel();
		if (nSel == -1)
			return 0;
		if (nSel != m_nSel && nSel != -1 && m_nSel != -1)
			m_tab.GetAt(m_tab.FindIndex(m_nSel)).pWnd->ShowWindow(SW_HIDE);
		m_tab.GetAt(m_tab.FindIndex(nSel)).pWnd->ShowWindow(SW_SHOW);
		m_nSel = nSel;

		return 0;
	}

	CCustomTabCtrl()
	{
		m_nSel = 0;
	}

	~CCustomTabCtrl()
	{
		int nCount = m_tab.GetCount();
		
		for (int i = 0; i < nCount; i++)
		{
			delete m_tab.GetAt(m_tab.FindIndex(i)).pWnd;
		}

		if (!::IsWindow(m_hWnd))
		{
			m_hWnd = NULL;
		}	
	}

	BOOL AddPage(CDialogImplBase* lpWndImpl, LPCTSTR lpstrTitle, int nImage = -1)
	{
		ATLASSERT(::IsWindow(lpWndImpl->m_hWnd));

		TABVIEWPAGE tvp = { 0 };
		TCITEM tci = { 0 };

		if (nImage == -1)
		{
			tci.iImage = nImage;
			tci.mask = TCIF_TEXT | TCIF_PARAM | TCIF_STATE;
		}
		else
		{
			tci.iImage = nImage;
			tci.mask = TCIF_IMAGE | TCIF_TEXT | TCIF_PARAM | TCIF_STATE;
		}

		int nItemCount = GetItemCount();
		tvp.pWnd = lpWndImpl;

		tci.pszText = (LPTSTR)lpstrTitle;
		tci.lParam = (LPARAM)lpWndImpl;
		// 插入当前页.
		InsertItem(nItemCount, &tci);
		m_tab.AddTail(tvp);
		// 显示当前页.
		if (nItemCount != 0)
		{
			for (int i = 0; i < nItemCount; i++)
			{
				m_tab.GetAt(m_tab.FindIndex(i)).pWnd->ShowWindow(SW_HIDE);
			}
		}
		m_nSel = nItemCount;
		Show();

		return TRUE;
	}

	BOOL DelPage(int nItem)
	{
		ATLASSERT(nItem < GetItemCount());

		DeleteItem(nItem);
		m_tab.GetAt(m_tab.FindIndex(nItem)).pWnd->ShowWindow(SW_HIDE);
		m_tab.RemoveAt(m_tab.FindIndex(nItem));
		m_nSel = nItem + 1;
		Show();

		return TRUE;
	}

	void Show(int nItem)
	{
		m_nSel = nItem;
		SetCurSel(m_nSel);
		m_tab.GetAt(m_tab.FindIndex(m_nSel)).pWnd->ShowWindow(SW_SHOW);
		int nItemCount = m_tab.GetCount();
		for (int i = 0; i < nItemCount; i++)
		{
			if (i != m_nSel)
				m_tab.GetAt(m_tab.FindIndex(i)).pWnd->ShowWindow(SW_HIDE);
		}

		SetRect();
	}

	void Show()
	{
		SetCurSel(m_nSel);
		m_tab.GetAt(m_tab.FindIndex(m_nSel)).pWnd->ShowWindow(SW_SHOW);
		int nItemCount = m_tab.GetCount();
		for (int i = 0; i < nItemCount; i++)
		{
			if (i != m_nSel)
				m_tab.GetAt(m_tab.FindIndex(i)).pWnd->ShowWindow(SW_HIDE);
		}

		SetRect();
	}

	void SetRect()
	{
		CRect tabRect, itemRect;
		int nX, nY, nCX, nCY;

		GetClientRect(&tabRect);
		GetItemRect(0, &itemRect);

		nX = tabRect.left + 1;
		nY = itemRect.bottom + 1;
		nCX = tabRect.right - nX - GetSystemMetrics(SM_CXDLGFRAME);
		nCY = tabRect.bottom - nY - GetSystemMetrics(SM_CYDLGFRAME);

		m_tab.GetAt(m_tab.FindIndex(m_nSel)).pWnd->SetWindowPos(HWND_TOP, nX, nY, nCX, nCY, SWP_SHOWWINDOW);
		
		int nItemCount = m_tab.GetCount();
		for (int i = 0; i < nItemCount; i++)
		{
			if (i != m_nSel)
				m_tab.GetAt(m_tab.FindIndex(i)).pWnd->SetWindowPos(HWND_TOP, nX, nY, nCX, nCY, SWP_HIDEWINDOW);
		}
	}

	LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		return 0;
	}

	LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		m_hWnd = NULL;
		return 0;
	}
};
